package contracts

import (
	"encoding/json"
	"github.com/hyperledger/fabric-contract-api-go/contractapi"
	"soa/contracts/model"
	"sort"
	"strings"
	"time"
)

// 初始化管理员账号
func (m *MallContract) Init(ctx contractapi.TransactionContextInterface, email string, pass string) error {
	//将admin的密码初始化
	var adminUser = model.AdminUser{
		Email: email,
		Pass:  pass,
		Head:  "https://daisyui.com/images/stock/photo-1534528741775-53994a69daeb.jpg", //使用初始化管理员头像
	}

	//将数据json化
	adminUserJson, err := json.Marshal(adminUser)
	if err != nil {
		return err
	}

	err = ctx.GetStub().PutState("admin", adminUserJson)
	if err != nil {
		return err
	}

	//初始化商家数组
	var allSeller []model.SupplierUser
	//将数据json化上传状态
	allSellerJson, err := json.Marshal(allSeller)
	if err != nil {
		return err
	}
	err = ctx.GetStub().PutState("suppliers", allSellerJson)
	if err != nil {
		return err
	}

	//初始化订单数组
	var allOrder []model.Order
	//将数据json化上传状态
	allOrderJson, err := json.Marshal(allOrder)
	if err != nil {
		return err
	}
	err = ctx.GetStub().PutState("orders", allOrderJson)
	if err != nil {
		return err
	}

	//初始化商品数组
	var allGoods []model.Good
	//将数据json化上传状态
	allGoodsJson, err := json.Marshal(allGoods)
	if err != nil {
		return err
	}
	err = ctx.GetStub().PutState("goods", allGoodsJson)
	if err != nil {
		return err
	}
	return nil
}

// 管理员登陆
func (m *MallContract) AdminLogin(ctx contractapi.TransactionContextInterface, email string, pass string) (bool, error) {
	//将admin的密码初始化
	if email == "admin" && pass == "admin" {
		return true, nil
	}
	return false, nil
}

// 获取今日信息
func (m *MallContract) GetTodayInfo(ctx contractapi.TransactionContextInterface) (model.TodayInfo, error) {
	// 实例化对象
	var data model.TodayInfo
	//获取所有商品信息
	state, err := ctx.GetStub().GetState("goods")
	if err != nil {
		return model.TodayInfo{}, err
	}
	var allGoods []model.Good
	err = json.Unmarshal(state, &allGoods)
	if err != nil {
		return model.TodayInfo{}, err
	}
	//初始化今日浏览
	data.TodayBrowsing = 0
	//获取今日时间 格式化到日
	t := time.Now().Format("2006-01-02")
	//循环遍历
	for i := 0; i < len(allGoods); i++ {
		for k, v := range allGoods[i].Browses {
			if k == t {
				data.TodayBrowsing += v.Number
			}
		}
	}

	//获取所有商品信息
	state, err = ctx.GetStub().GetState("orders")
	if err != nil {
		return model.TodayInfo{}, err
	}
	var allOrder []model.Good
	err = json.Unmarshal(state, &allOrder)
	if err != nil {
		return model.TodayInfo{}, err
	}

	//获取今日订单数
	data.TodayOrder = 0 //处理化为0
	for i := 0; i < len(allOrder); i++ {
		if allOrder[i].CreateTime == t {
			data.TodayOrder++
		}
	}

	//获取今日新增商品
	data.NewAddGoods = 0 //处理化为0
	//遍历所有商品
	for i := 0; i < len(allGoods); i++ {
		if allGoods[i].CreateTime == t {
			data.NewAddGoods++
		}
	}

	return data, nil
}

// 获取今日商品销量排行
func (m *MallContract) GetTodayGoodsRank(ctx contractapi.TransactionContextInterface) ([]model.Good, error) {
	//获取所有订单信息
	state, err := ctx.GetStub().GetState("orders")
	if err != nil {
		return []model.Good{}, err
	}
	//实例化订单对象
	var allOrder []model.Order
	err = json.Unmarshal(state, &allOrder)
	if err != nil {
		return []model.Good{}, err
	}

	//获取今日时间 格式化到日
	t := time.Now().Format("2006-01-02")

	//储存今日订单
	sales := make(map[string]int)

	//获取今日订单
	for i := 0; i < len(allOrder); i++ {
		if allOrder[i].CreateTime == t {
			for _, good := range allOrder[i].GoodsInfo {
				sales[good.Id] += good.Stock // add sales count of each good
			}
		}
	}

	//从sales中获取销量前十的商品
	type SaleCount struct {
		GoodId string
		Count  int
	}

	salesSlice := make([]SaleCount, 0, len(sales))
	for k, v := range sales {
		salesSlice = append(salesSlice, SaleCount{k, v})
	}

	sort.Slice(salesSlice, func(i, j int) bool {
		return salesSlice[i].Count > salesSlice[j].Count // descending order
	})

	if len(salesSlice) > 10 {
		salesSlice = salesSlice[:10] // get the top 10
	}

	//获取排行前10的商品
	var todayGoodsRank []model.Good
	for i := 0; i < len(salesSlice); i++ {
		//获取商品信息
		var goods model.Good
		getState, err := ctx.GetStub().GetState(salesSlice[i].GoodId)
		if err != nil {
			return []model.Good{}, err
		}
		json.Unmarshal(getState, &goods)
		//将销售替换成销量
		goods.Sales = salesSlice[i].Count
		todayGoodsRank = append(todayGoodsRank, goods)
	}

	return todayGoodsRank, nil
}

// 获取商品列表
func (m *MallContract) GetGoodsList(ctx contractapi.TransactionContextInterface) ([]model.Good, error) {
	//储存所有商品信息
	var data []model.Good
	state, err := ctx.GetStub().GetState("goods")
	if err != nil {
		return []model.Good{}, err
	}

	err = json.Unmarshal(state, &state)
	if err != nil {
		return []model.Good{}, err
	}

	return data, nil
}

// 实现商品搜索
func (m *MallContract) SearchGoods(ctx contractapi.TransactionContextInterface, keyword string) ([]model.Good, error) {
	//储存所有商品信息
	var data []model.Good
	state, err := ctx.GetStub().GetState("goods")
	if err != nil {
		return []model.Good{}, err
	}

	err = json.Unmarshal(state, &data)
	if err != nil {
		return []model.Good{}, err
	}

	//遍历所有商品
	for i := 0; i < len(data); i++ {
		//判断商品名是否包含关键字
		if strings.Contains(data[i].Name, keyword) {
			data = append(data, data[i])
		}
	}

	return data, nil
}

// 获取商品详情页
func (m *MallContract) GetGoodsDetail(ctx contractapi.TransactionContextInterface, id string) (model.Good, error) {
	//实例化对象
	var data model.Good
	//获取商品信息
	state, err := ctx.GetStub().GetState(id)
	if err != nil {
		return model.Good{}, err
	}

	err = json.Unmarshal(state, &data)
	if err != nil {
		return model.Good{}, err
	}

	return data, nil
}

// 实现修改商品状态
func (m *MallContract) ChangeGoodsStatus(ctx contractapi.TransactionContextInterface, id string, status int) error {
	//通过商品ID获取商家信息
	state, err := ctx.GetStub().GetState(id)
	if err != nil {
		return err
	}

	var goods model.Good
	err = json.Unmarshal(state, &goods)
	if err != nil {
		return err
	}

	//修改商品状态
	goods.Status = status
	//上传状态
	goodsJson, err := json.Marshal(goods)
	if err != nil {
		return err
	}
	err = ctx.GetStub().PutState(id, goodsJson)
	if err != nil {
		return err
	}

	//更换商家列表里面的商品信息
	state, err = ctx.GetStub().GetState(goods.Supplier)
	if err != nil {
		return err
	}

	var supplier model.SupplierUser
	err = json.Unmarshal(state, &supplier)
	if err != nil {
		return err
	}

	//遍历商家商品列表 如果商品ID等于传入的ID 则修改商品状态
	for i := 0; i < len(supplier.Goods); i++ {
		if supplier.Goods[i].Id == id {
			supplier.Goods[i] = goods
		}
	}

	// 将修改后的商家对象上传状态
	supplierJson, err := json.Marshal(supplier)
	if err != nil {
		return err
	}

	err = ctx.GetStub().PutState(goods.Supplier, supplierJson)
	if err != nil {
		return err
	}

	//更改商品列表里面商品信息
	state, err = ctx.GetStub().GetState("goods")
	var allGoods []model.Good
	err = json.Unmarshal(state, &allGoods)
	if err != nil {
		return err
	}

	for i := 0; i < len(allGoods); i++ {
		if allGoods[i].Id == id {
			allGoods[i] = goods
		}
	}

	//上传状态
	allGoodsJson, err := json.Marshal(allGoods)
	if err != nil {
		return err
	}

	err = ctx.GetStub().PutState("goods", allGoodsJson)
	if err != nil {
		return err
	}

	return nil
}

// 获取所有待审核的商品
func (m *MallContract) GetPendingGoods(ctx contractapi.TransactionContextInterface) ([]model.Good, error) {
	//获取所有商品
	state, err := ctx.GetStub().GetState("goods")
	if err != nil {
		return []model.Good{}, err
	}

	var goods []model.Good
	err = json.Unmarshal(state, &goods)
	if err != nil {
		return []model.Good{}, err
	}

	var pending []model.Good
	for i := 0; i < len(goods); i++ {
		if goods[i].Status == 0 { //代表待审核
			pending = append(pending, goods[i])
		}
	}

	return pending, nil
}

// 获取所有订单信息
func (m *MallContract) GetAllOrders(ctx contractapi.TransactionContextInterface) ([]model.Order, error) {
	state, err := ctx.GetStub().GetState("orders")
	if err != nil {
		return []model.Order{}, err
	}

	//实例化订单对象
	var orders []model.Order
	err = json.Unmarshal(state, &orders)
	if err != nil {
		return []model.Order{}, err
	}

	return orders, nil
}

// 通过订单ID实现订单搜索
func (m *MallContract) SearchOrderById(ctx contractapi.TransactionContextInterface, id string) (model.Order, error) {
	//获取所有订单信息
	state, err := ctx.GetStub().GetState(id)
	if err != nil {
		return model.Order{}, err
	}

	//实例化订单对象
	var orders model.Order
	err = json.Unmarshal(state, &orders)
	if err != nil {
		return model.Order{}, err
	}

	return orders, nil
}

// 获取所有商家列表
func (m *MallContract) GetAllSuppliers(ctx contractapi.TransactionContextInterface) ([]model.SupplierUser, error) {
	//获取所有商家信息
	state, err := ctx.GetStub().GetState("suppliers")
	if err != nil {
		return []model.SupplierUser{}, err
	}

	//实例化商家对象
	var suppliers []model.SupplierUser
	err = json.Unmarshal(state, &suppliers)
	if err != nil {
		return []model.SupplierUser{}, err
	}

	return suppliers, nil
}

// 通过商家ID搜索商家信息
func (m *MallContract) SearchSupplierById(ctx contractapi.TransactionContextInterface, id string) (model.SupplierUser, error) {
	state, err := ctx.GetStub().GetState(id)
	if err != nil {
		return model.SupplierUser{}, err
	}

	var supplier model.SupplierUser
	err = json.Unmarshal(state, &supplier)
	if err != nil {
		return model.SupplierUser{}, err
	}

	return supplier, nil
}

// 通过商家ID获取商家的订单信息
func (m *MallContract) GetSupplierOrders(ctx contractapi.TransactionContextInterface, id string) ([]model.Order, error) {
	//获取所有订单信息
	state, err := ctx.GetStub().GetState(id)
	if err != nil {
		return []model.Order{}, err
	}

	//实例化订单对象
	var supplier model.SupplierUser
	err = json.Unmarshal(state, &supplier)
	if err != nil {
		return []model.Order{}, err
	}

	return supplier.Orders, nil
}
